package org.atf.services;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.atf.model.entity.Server;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
import org.directwebremoting.ScriptSessions;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.impl.DaemonThreadFactory;


public class ServerTaskStatusUpdater implements Runnable{
	

	public ServerTaskStatusUpdater(){
		ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5,new DaemonThreadFactory());
		executor.scheduleAtFixedRate(this, 0, 20, TimeUnit.SECONDS);
	}
	
	public void run() {
		updateAllTasks();
	}

	public void updateAllTasks(){
	// TODO Auto-generated method stub
			//System.out.println(Calendar.getInstance().getTime()+" : running the Task StatusUpdater");
			List<TaskStatus> task = new ArrayList<TaskStatus>();
			List<TaskStatus> appTasks=TaskManager.getInstance().getAllAppTaskStatus();
					
			for(TaskStatus ts: appTasks){
				ts.setTaskId("S"+ts.getTaskId());
			}
			task.addAll(appTasks);
			for(TaskStatus ts: appTasks){
				updateTaskStatusList(ts);		
				try {
					Thread.sleep(100L);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			
			List<TaskStatus> profileTasks=TaskManager.getInstance().getAllProfileTaskStatus();
			for(TaskStatus ts: profileTasks){
				ts.setTaskId("P"+ts.getTaskId());
				updateProfileTaskStatus(ts);
				try {
					Thread.sleep(100L);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
	}
	
	
	public void updateTaskStatusList(final TaskStatus ts){
		
		Integer serverId=Integer.valueOf(ts.getServerId());
        
		Browser.withAllSessionsFiltered(new ServerEnabledFilter(serverId),new Runnable(){

			public void run() {
				// TODO Auto-generated method stub
				
				ScriptSessions.addFunctionCall("uft.updateServerTaskStatus", ts);
			}
			
		});
		
		
	}
	public void updateProfileTaskStatus(final TaskStatus ts){
		Integer profileid=Integer.valueOf(ts.getProfileId());
		Browser.withAllSessionsFiltered(new ProfileEnabledFilter(profileid),new Runnable(){

			public void run() {
				// TODO Auto-generated method stub
				
				ScriptSessions.addFunctionCall("uft.updateServerTaskStatus", ts);
			}
			
		});
	}
	
	 public class ServerEnabledFilter implements ScriptSessionFilter {
		 
		 private Integer serverId;
		 
		 public ServerEnabledFilter(Integer serverId){
			 this.serverId=serverId;
		 }

		public boolean match(ScriptSession arg0) {
			// TODO Auto-generated method stub
			Object check = arg0.getAttribute(SERVER_ID_SESSION_ATTR);
			if(check != null ){
				List<Integer> serverIds=(List<Integer>) check;
				if(serverIds.contains(serverId)){
					return true;
				}
			}
			return false;
		}
		 
	 }
	 
public class ProfileEnabledFilter implements ScriptSessionFilter {
		 
		 private Integer profileId;
		 
		 public ProfileEnabledFilter(Integer profileId){
			 this.profileId=profileId;
		 }

		public boolean match(ScriptSession arg0) {
			// TODO Auto-generated method stub
			Object check = arg0.getAttribute(PROFILE_ID_SESSION_ATTR);
			if(check != null ){
				List<Integer> profileIds=(List<Integer>) check;
				if(profileIds.contains(profileId)){
					return true;
				}
			}
			return false;
		}
		 
	 }
	
     public void NotifyAll(TaskStatus ts){
    	 updateTaskStatusList(ts);
     }
	 
	 public void addServersIdToScriptSession(List<Integer> serverId) {
	        ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
	        scriptSession.setAttribute(SERVER_ID_SESSION_ATTR, serverId);
	 }
	 
	 public void addProfileIdToScriptSession(List<Integer> profileId) {
	        ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
	        scriptSession.setAttribute(PROFILE_ID_SESSION_ATTR, profileId);
	 }
	 public void removeProfileIdToScriptSession(){
		 ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
	     scriptSession.removeAttribute(PROFILE_ID_SESSION_ATTR);
	 }
	 public void removeServersIdToScriptSession(){
		 ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
	     scriptSession.removeAttribute(SERVER_ID_SESSION_ATTR);
	 }
	 
	 private final static String SERVER_ID_SESSION_ATTR = "SERVER_ID_SESSION_ATTR";
	 private final static String PROFILE_ID_SESSION_ATTR = "PROFILE_ID_SESSION_ATTR";
}
